/*
 * @Author: 9ilk 3535851673@qq.com
 * @Date: 2024-11-29 21:36:53
 * @LastEditors: 9ilk 3535851673@qq.com
 * @LastEditTime: 2025-01-03 21:07:02
 * @FilePath: /zhuang/RingBuffer/RingBuffer.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/*
 * @Author: 9ilk 3535851673@qq.com
 * @Date: 2024-11-29 21:36:53
 * @LastEditors: 9ilk 3535851673@qq.com
 * @LastEditTime: 2024-11-30 20:19:58
 * @FilePath: /zhuang/RingBuffer/RingBuffer.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once
#include<semaphore.h>
#include"Sem.hpp"
#include <iostream>
#include<pthread.h>
#include <vector>
using namespace std;
using namespace SemModule;

namespace RingBufferModule
{
    template <typename T>
    class RingBuffer
    {
    public:
        RingBuffer(int cap)
        :_ring(cap),
         _cap(cap),
         _p_step(0),
         _c_step(0),
         _datasem(0),
         _spacesem(cap)
        {
           
        };
        ~RingBuffer() 
        {
          
        };
        void Equeue(const T& in) //生产者做
        {
            //必须保证调用接口的安全就得引入信号量
            _spacesem.P();//生产者申请空间
            _ring[_p_step] = in; //生产
            _p_step++;
            _p_step %= _cap; //保证环形特性
            //生产者 不可能生产满
            _datasem.V(); //生产者释放数据
        }
        void Pop(T*out)
        {
            _datasem.P(); //预订数据
            //消费
            *out = _ring[_c_step];
            _c_step++;
            _c_step %= _cap; //保持环形特征 
            _spacesem.V(); //释放空间
        }
    private:
        vector<T> _ring; //环,临界资源
        int _cap; //总容量
        //表明生产消费者的位置
        int _p_step;
        int _c_step;
        Sem _datasem; //数据信号量
        Sem _spacesem; //空间信号量
    };

}